﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferenceReviewPerson")]
	public class ConferenceReviewPersonController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferenceReviewPerson;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferenceReviewPersonModel();
			model.ConferenceId = conferenceId;
			model.IsReview = conferenceMaster.IsReview;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferenceReviewPersonModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

			var IsInternational = conferenceMaster.IsInternational;

			var sql = DbContext.ReviewPersonMaster.AsNoTracking()
					.Where(x => !string.IsNullOrEmpty(x.Status) &&
						x.ConferenceId == model.ConferenceId)
					.Join(DbContext.SysUserMaster.AsNoTracking(),
						reviewer => reviewer.UserId,
						user => user.ID,
						(reviewer, user) => new
						{
							UserId = reviewer.UserId,
							UserName = user.UserName,
							FullName = user.FullName,
							ID = reviewer.ID,
							ConferenceId = reviewer.ConferenceId,
							IsFinalReviewer = reviewer.IsFinalReviewer,
							IsFirstReviewer = reviewer.IsFirstReviewer,
							Status = reviewer.Status,
							Sort = reviewer.Sort,
							Remark = reviewer.Remark,
							Creator = reviewer.Creator,
							CreateIP = reviewer.CreateIP,
							CreateDate = reviewer.CreateDate,
							UpdateDate = reviewer.UpdateDate
						}
					);

			if (!string.IsNullOrWhiteSpace(model.SelUserName))
			{
				sql = sql.Where(x => x.FullName.Contains(model.SelUserName));
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.UpdateDate).ThenBy(x => x.UserName).Skip(skip).Take(take);
			}

			var sqlResult = sql.ToList()
				.Select(x => new
				{
					UserId = x.UserId,
					UserName = x.UserName,
					FullName = x.FullName,
					ID = x.ID,
					ConferenceId = x.ConferenceId,
					IsFinalReviewer = x.IsFinalReviewer,
					IsFirstReviewer = x.IsFirstReviewer,
					Status = x.Status,
					Sort = x.Sort,
					Remark = x.Remark,
					Creator = x.Creator,
					CreateIP = x.CreateIP,
					CreateDate = IsInternational ? x.CreateDate.Value.ToString("MM/dd/yyyy") :
							x.CreateDate.Value.ToString("yyyy-MM-dd")
				});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = sqlResult,
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Delete/{ConferenceId}")]
		public async Task<JsonResult> Delete(ConferenceReviewPersonModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.ReviewInfo.AsNoTracking()
					.Where(x => x.UserId == model.Id && x.Status != ConstValues.ContributationStatus.待审).ToListAsync();

			if (exist.Count > 0)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgUsingCanNotDelete),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.ReviewPersonMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				using (var transaction = DbContext.Database.BeginTransaction())
				{
					var reviewInfoData = await DbContext.ReviewInfo.Where(x => x.UserId == result.UserId).ToListAsync();

					DbContext.ReviewInfo.RemoveRange(reviewInfoData);

					DbContext.ReviewPersonMaster.Remove(result);

					await DbContext.SaveChangesAsync();
					transaction.Commit();
				}
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetUserData(ConferenceUserMasterModel model)
		{
			var sql = DbContext.SysUserMaster.AsNoTracking().Where(x => x.Status == ConstValues.Status.正常);
			if (!string.IsNullOrWhiteSpace(model.SelAddMail))
			{
				sql = sql.Where(x => x.Mail.Contains(model.SelAddMail));
			}
			if (!string.IsNullOrWhiteSpace(model.SelAddName))
			{
				sql = sql.Where(x => x.UserName.Contains(model.SelAddName));
			}
			if (string.IsNullOrWhiteSpace(model.SelAddMail) && string.IsNullOrWhiteSpace(model.SelAddName))
			{
				sql = sql.Where(x => x.Mail.Contains(model.SelAddMail) && x.UserName.Contains(model.SelAddName));
			}
			int total = await sql.CountAsync();
			sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.CreateDate);

			var sqlResult = await sql.ToListAsync();
			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				UserName = x.UserName,
				Mail = x.Mail,
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Create/{ConferenceId}")]
		public async Task<JsonResult> Create(ConferenceReviewPersonModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

			var ids = model.AllId.Split(ConstValues.chrAnd);
			for (int index = 0; index < ids.Length; index++)
			{
				string tmp = ids[index];
				var result = await DbContext.ReviewPersonMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.UserId == tmp);

				if (result == null)
				{
					var reviewPersonMaster = new ReviewPersonMaster
					{
						ID = Utility.GetTableId(ConstValues.TableName.ReviewPersonMaster),
						ConferenceId = model.ConferenceId,
						UserId = tmp,
						IsFirstReviewer = conferenceMaster.IsReview ? model.IsFirstReviewer : true,
						IsFinalReviewer = conferenceMaster.IsReview ? model.IsFinalReviewer : false,
						Status = model.Status,
						Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
						Remark = model.Remark?.Trim(),
						Creator = LoginUser.UserName,
						CreateIP = LoginUser.IP,
						CreateDate = DateTime.Now
					};
					DbContext.ReviewPersonMaster.Add(reviewPersonMaster);
				}
				else
				{
					return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.ReviewPerson)),
						JsonRequestBehavior.AllowGet);
				}
			}

			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditData(string id)
		{
			var result = await DbContext.ReviewPersonMaster.AsNoTracking()
					.Where(x => x.ID == id)
					.Join(DbContext.SysUserMaster.AsNoTracking(),
						reviewer => reviewer.UserId,
						user => user.ID,
						(reviewer, user) => new
						{
							Mail = user.Mail,
							UserName = user.FullName,
							IsFinalReviewer = reviewer.IsFinalReviewer ? ConstValues.GenericSelectionType.有 : ConstValues.GenericSelectionType.无,
							IsFirstReviewer = reviewer.IsFirstReviewer ? ConstValues.GenericSelectionType.有 : ConstValues.GenericSelectionType.无
						}
					)
					.FirstOrDefaultAsync();

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Modify/{ConferenceId}")]
		public async Task<JsonResult> Modify(ConferenceReviewPersonModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ReviewPersonMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				result.IsFinalReviewer = model.IsFinalReviewer;
				result.Updater = LoginUser.UserName;
				result.UpdateIP = LoginUser.IP;
				result.UpdateDate = DateTime.Now;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		//专题
		public async Task<JsonCamelCaseResult> GetTopicList(string conferenceId)
		{
			var topicList = DbContext.ConferenceContributeInfo.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId)
					.GroupBy(x => x.TopicId)
					.Select(x => x.Key).ToList();

			var sql = DbContext.TopicMaster.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId &&
						x.Status == ConstValues.Status.正常 &&
						topicList.Contains(x.ID));

			sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.CreateDate);

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.ID,
				TopicName = x.TopicName
			});

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}
		//论文类型
		public async Task<JsonCamelCaseResult> GetEssayTypeList(string conferenceId)
		{
			var essayList = DbContext.ConferenceContributeInfo.AsNoTracking()
						.Where(x => x.ConferenceId == conferenceId)
						.GroupBy(x => x.EssayId)
						.Select(x => x.Key).ToList();

			var sql = DbContext.EssayMaster.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId &&
					x.Status == ConstValues.Status.正常 &&
					essayList.Contains(x.ID));

			sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.CreateDate);

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.ID,
				EssayType = x.EssayType
			});

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}
		//报告类型
		public async Task<JsonCamelCaseResult> GetReportTypeList(string conferenceId)
		{
			var reportList = DbContext.ConferenceContributeInfo.AsNoTracking()
							.Where(x => x.ConferenceId == conferenceId)
							.GroupBy(x => x.ReportId)
							.Select(x => x.Key).ToList();

			var sql = DbContext.ReportMaster.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId &&
					x.Status == ConstValues.Status.正常 &&
					reportList.Contains(x.ID));

			sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.CreateDate);

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.ID,
				ReportType = x.ReportType
			});

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		//未分配稿件
		public async Task<JsonCamelCaseResult> GetNotDistributed(string conferenceId, string userId, string topicId, string essayTypeId, string reportTypeId)
		{
			var sql = DbContext.ConferenceContributeInfo.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId);

			if (!string.IsNullOrEmpty(topicId))
			{
				sql = sql.Where(x => x.TopicId == topicId);
			}

			if (!string.IsNullOrEmpty(essayTypeId))
			{
				sql = sql.Where(x => x.EssayId == essayTypeId);
			}

			if (!string.IsNullOrEmpty(reportTypeId))
			{
				sql = sql.Where(x => x.ReportId == reportTypeId);
			}

			var distributed = await sql.Join(DbContext.ReviewInfo.AsNoTracking()
					.Where(x => x.UserId == userId),
					contribute => contribute.ID,
					review => review.ContributeId,
					(contribute, review) => new
					{
						contribute.ID
					})
				.Select(x => x.ID)
				.ToListAsync();

			sql = sql.Where(x => x.ContributationStatus != ConstValues.ContributationStatus.录用 &&
							x.ContributationStatus != ConstValues.ContributationStatus.不录用 &&
							!distributed.Contains(x.ID));

			var sqlResult = await sql.OrderBy(x => x.Sort)
					.ThenBy(x => x.EssayTitle)
					.Select(x => new EssayCountModel
					{
						Id = x.ID,
						Name = x.EssayTitle
					})
					.ToListAsync();

			sqlResult.ForEach(x =>
			{
				x.ReviewCount = DbContext.ReviewInfo.AsNoTracking().Count(y => y.ContributeId == x.Id);
			});

			var result = sqlResult.Select(x => new
			{
				Id = x.Id,
				EssayTitle = x.Name,
				ReviewCount = x.ReviewCount
			});

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		//已分配稿件
		public async Task<JsonCamelCaseResult> GetDistributed(string conferenceId, string userId, string topicId, string essayTypeId, string reportTypeId)
		{
			var sql = DbContext.ConferenceContributeInfo.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId);

			if (!string.IsNullOrEmpty(topicId))
			{
				sql = sql.Where(x => x.TopicId == topicId);
			}

			if (!string.IsNullOrEmpty(essayTypeId))
			{
				sql = sql.Where(x => x.EssayId == essayTypeId);
			}

			if (!string.IsNullOrEmpty(reportTypeId))
			{
				sql = sql.Where(x => x.ReportId == reportTypeId);
			}

			var distributed = await sql.Join(DbContext.ReviewInfo.AsNoTracking()
					.Where(x => x.UserId == userId && x.Result == ConstValues.ContributationStatus.待审),
					contribute => contribute.ID,
					review => review.ContributeId,
					(contribute, review) => new
					{
						Id = contribute.ID,
						EssayTitle = contribute.EssayTitle
					})
				.OrderBy(x => x.EssayTitle)
				.Select(x => new EssayCountModel
				{
					Id = x.Id,
					Name = x.EssayTitle
				})
				.ToListAsync();

			distributed.ForEach(x =>
			{
				x.ReviewCount = DbContext.ReviewInfo.AsNoTracking().Count(y => y.ContributeId == x.Id);
			});

			var result = distributed.Select(x => new
			{
				Id = x.Id,
				EssayTitle = x.Name,
				ReviewCount = x.ReviewCount
			});

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("SaveDistribution/{ConferenceId}")]
		public async Task<JsonResult> SaveDistribution(ConferenceReviewPersonModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var finalReviewEssay = string.Empty;
			var reviewPersonMaster = await DbContext.ReviewPersonMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId && x.UserId == model.UserId);

			// 终审专家时，检查是否有稿件已经被安排为非本人终审专家
			if (reviewPersonMaster.IsFinalReviewer == true)
			{
				if (model.EssayIdList != null)
				{
					var conferenceInfo = await DbContext.ConferenceMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

					foreach (var essay in model.EssayIdList)
					{
						var distributed = await DbContext.ReviewInfo.AsNoTracking()
							.FirstOrDefaultAsync(x => x.IsFinalReview &&
								x.ConferenceId == model.ConferenceId &&
								x.ContributeId == essay.EssayId &&
								x.UserId != model.UserId);

						if (distributed != null)
						{
							var username = string.Empty;
							if (distributed.UserId != null)
							{
								var userInfo = await DbContext.SysUserMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == distributed.UserId);
								username = userInfo.UserName;
							}

							var contributeInfo = await DbContext.ConferenceContributeInfo.AsNoTracking()
									.FirstOrDefaultAsync(x => x.ID == essay.EssayId);

							finalReviewEssay += string.Format(Resources.MsgFinalReviewerExist, contributeInfo.EssayTitle, username) + "\r\n";
						}
					}
				}
			}

			if (!string.IsNullOrEmpty(finalReviewEssay))
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(finalReviewEssay), JsonRequestBehavior.AllowGet);
			}

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				var sql = DbContext.ConferenceContributeInfo.AsNoTracking()
						.Where(x => x.ConferenceId == model.ConferenceId);

				if (model.TypeId.Contains(ConstValues.TableId.EssayMaster))
				{
					sql = sql.Where(x => x.EssayId == model.TypeId);
				}
				else if (model.TypeId.Contains(ConstValues.TableId.TopicMaster))
				{
					sql = sql.Where(x => x.TopicId == model.TypeId);
				}
				else if (model.TypeId.Contains(ConstValues.TableId.ReportMaster))
				{
					sql = sql.Where(x => x.ReportId == model.TypeId);
				}
				var contributeIdList = await sql.Select(x => x.ID).ToListAsync();

				var reviewInfoData = await DbContext.ReviewInfo
					.Where(x => x.ConferenceId == model.ConferenceId &&
						x.UserId == model.UserId &&
						contributeIdList.Contains(x.ContributeId) &&
						x.Result == ConstValues.ContributationStatus.待审)
					.ToListAsync();

				DbContext.ReviewInfo.RemoveRange(reviewInfoData);

				if (model.EssayIdList != null)
				{
					foreach (var essay in model.EssayIdList)
					{
						if (reviewPersonMaster.IsFirstReviewer)
						{
							var reviewInfo = new ReviewInfo
							{
								ID = Utility.GetTableId(ConstValues.TableName.ReviewInfo),
								ConferenceId = model.ConferenceId,
								UserId = model.UserId,
								ContributeId = essay.EssayId,
								Quality = 0,
								Evaluation = 0,
								Advantage = string.Empty,
								Defect = string.Empty,
								Others = string.Empty,
								Result = ConstValues.ContributationStatus.待审,
								Status = ConstValues.Status.正常,
								Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
								Remark = model.Remark?.Trim(),
								Creator = LoginUser.UserName,
								CreateIP = LoginUser.IP,
								CreateDate = DateTime.Now,
								IsFinalReview = false
							};
							DbContext.ReviewInfo.Add(reviewInfo);
						}

						//if (reviewPersonMaster.IsFinalReviewer)
						//{
						//	var reviewInfo = new ReviewInfo
						//	{
						//		ID = Utility.GetTableId(ConstValues.TableName.ReviewInfo),
						//		ConferenceId = model.ConferenceId,
						//		UserId = model.UserId,
						//		ContributeId = essay.EssayId,
						//		Quality = 0,
						//		Evaluation = 0,
						//		Advantage = string.Empty,
						//		Defect = string.Empty,
						//		Others = string.Empty,
						//		Result = ConstValues.ContributationStatus.待审,
						//		Status = ConstValues.Status.正常,
						//		Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
						//		Remark = model.Remark?.Trim(),
						//		Creator = LoginUser.UserName,
						//		CreateIP = LoginUser.IP,
						//		CreateDate = DateTime.Now,
						//		IsFinalReview = true
						//	};
						//	DbContext.ReviewInfo.Add(reviewInfo);
						//}
					}
				}
				await DbContext.SaveChangesAsync();
				transaction.Commit();
			}
			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		//终审列表
		public async Task<JsonCamelCaseResult> GetFinalList(string conferenceId, string userId, string selEssayTitle, string selContributionID)
		{
			var finishList = await DbContext.ReviewInfo.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId &&
						x.Result != ConstValues.ContributationStatus.待审 &&
						x.IsFinalReview)
					.Select(x => x.ContributeId)
					.ToListAsync();

			var unfinishList = await DbContext.ReviewInfo.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId &&
						x.Result == ConstValues.ContributationStatus.待审)
					.Select(x => x.ContributeId)
					.ToListAsync();

			var sql = DbContext.ReviewInfo.AsNoTracking()
					.Where(x => x.ConferenceId == conferenceId && 
							x.Result == ConstValues.ContributationStatus.待审 &&
							x.IsFinalReview &&
							unfinishList.Contains(x.ContributeId))
						.Select(x => new
						{
							ContributeId = x.ContributeId,
							UserId = x.UserId,
						})
					.Union(DbContext.ReviewInfo.AsNoTracking()
						.Where(x => x.ConferenceId == conferenceId &&
							x.Result != ConstValues.ContributationStatus.待审 &&
							!x.IsFinalReview &&
							!unfinishList.Contains(x.ContributeId) &&
							!finishList.Contains(x.ContributeId))
						.Select(x => new
						{
							ContributeId = x.ContributeId,
							UserId = string.Empty
						})
						.Distinct())
					.Join(DbContext.ConferenceContributeInfo.AsNoTracking()
						.Where(x => x.ConferenceId == conferenceId),
						review => review.ContributeId,
						contribute => contribute.ID,
						(review, contribute) => new
						{
							IsSelf = review.UserId == userId ? true : false,
							ContributeId = contribute.ID,
							EssayTitle = contribute.EssayTitle,
							UserId = review.UserId
						}
					);

			if (!string.IsNullOrEmpty(selContributionID))
			{
				sql = sql.Where(x => x.ContributeId.Contains(selContributionID));
			}

			if (!string.IsNullOrEmpty(selEssayTitle))
			{
				sql = sql.Where(x => x.EssayTitle.Contains(selEssayTitle));
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				IsSelf = x.IsSelf,
				Id = x.ContributeId,
				EssayTitle = x.EssayTitle,
				UserId = x.UserId,
				UserName = DbContext.SysUserMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.UserId)?.UserName
			})
			.OrderByDescending(x => x.IsSelf).ThenBy(x => x.Id);

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("SaveFinal/{ConferenceId}")]
		public async Task<JsonResult> SaveFinal(ConferenceReviewPersonModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var ids = model.AllId.Split(ConstValues.chrComma);
			var exist = await DbContext.ReviewInfo
					.Where(x => x.ConferenceId == model.ConferenceId &&
						x.Result == ConstValues.ContributationStatus.待审 &&
						x.IsFinalReview &&
						x.UserId == model.UserId)
					.ToListAsync();

			exist.ForEach(x =>
			{
				if (!ids.Contains(x.ContributeId))
				{
					DbContext.ReviewInfo.Remove(x);
				}
			});

			for (int index = 0; index < ids.Length; index++)
			{
				string tmp = ids[index];
				var result = await DbContext.ReviewInfo
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.Result == ConstValues.ContributationStatus.待审 &&
						x.IsFinalReview &&
						x.ContributeId == tmp);

				if (result == null)
				{
					var reviewInfo = new ReviewInfo
					{
						ID = Utility.GetTableId(ConstValues.TableName.ReviewInfo),
						ConferenceId = model.ConferenceId,
						UserId = model.UserId,
						ContributeId = tmp,
						Quality = 0,
						Evaluation = 0,
						Advantage = string.Empty,
						Defect = string.Empty,
						Others = string.Empty,
						Result = ConstValues.ContributationStatus.待审,
						Status = ConstValues.Status.正常,
						Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
						Remark = model.Remark?.Trim(),
						Creator = LoginUser.UserName,
						CreateIP = LoginUser.IP,
						CreateDate = DateTime.Now,
						IsFinalReview = true
					};
					DbContext.ReviewInfo.Add(reviewInfo);
				}
				else
				{
					if (result.UserId != model.UserId)
					{
						result.UserId = model.UserId;
						result.Updater = LoginUser.UserName;
						result.UpdateIP = LoginUser.IP;
						result.UpdateDate = DateTime.Now;
					}
				}
			}

			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}
	}
}